package com.github.io.filter;

import com.github.io.entity.User;
import com.github.io.service.IUserService;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.*;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liry
 * @version 1.0
 * @date Created on 2022/8/30 15:21
 * Description: 登录过滤器
 */
//@Component
public class LoginFilter implements Filter {

    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private IUserService userService;

    public static final String TOKEN = "Authorization";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 1. 校验请求token是否存在，存在是否有效
        // 2. 请求信息中没有token信息，则禁止访问系统，并强制跳转登录页
        // 2.1 用户登录时，校验用户账号密码是否正确。正确，生成token信息、获取用户信息、用户session信息并将相关信息进行缓存;失败，则返回登录页；
        // 3. 请求信息中有token信息，校验token是否有效。token失效则强制退出并返回登录页；token正确则放行；


        // 获取请求token
        String authorization = request.getHeader(TOKEN);

        // 缓存中存在key，直接放行
        if (!redisTemplate.hasKey(authorization)) {
            // 首次登录时，则需要校验账号密码
            User loginUser = userService.checkLoginInfo();
            if (!ObjectUtils.isEmpty(loginUser)) {
                Map<String, Object> cacheData = new HashMap<>();
                // 账号密码正确，生成token并进行缓存
                String token = createToken(loginUser);

                // 获取用户session信息
                HttpSession session = request.getSession();
                String sessionId = session.getId();
                long creationTime = session.getCreationTime();
                long lastAccessedTime = session.getLastAccessedTime();

                cacheData.put("userInfo", loginUser);
                cacheData.put("sessionId", sessionId);
                cacheData.put("createTime", creationTime);
                cacheData.put("lastAccessedTime", lastAccessedTime);
                // 将token信息、session、loginUser信息存储到redis
                redisTemplate.opsForValue().set(token, cacheData);

                // 过滤器放行
                filterChain.doFilter(servletRequest, servletResponse);
            } else if (redisTemplate.getExpire(authorization) > 0) {
                // token 在有效期内，则直接放行
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    // 根据用户信息生成token
    private String createToken(User loginUser) {
        return TOKEN;
    }

    @Override
    public void destroy() {

    }
}
